{
  Copyright 2012 Sergey Ostanin

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
}

program irenEditor;

uses
  Interfaces, Classes, SysUtils, Translator, Forms,

  SelectQuestionScreen, InputQuestionScreen, MatchQuestionScreen,
  OrderQuestionScreen, ClassifyQuestionScreen,

  SelectQuestionEditor, InputQuestionEditor, MatchQuestionEditor,
  OrderQuestionEditor, ClassifyQuestionEditor,

  SetEvaluationModelModifierEditor, ScriptModifierEditor,

  Windows, Messages, MiscUtils, VisualUtils, Shell, UnicodeCommandLine, Transmitter;

{$R *.rc}

resourcestring
  SIren = 'Iren';

const
  MAIN_WINDOW_PROPERTY_NAME = 'irenproject.ru-editorMainWindowProperty';

procedure ActivateExistingInstance;
var
  WindowHandle: HWND;
  cds: TCopyDataStruct;
  FileName: String;
begin
  WindowHandle := GetWindowWithProperty(MAIN_WINDOW_PROPERTY_NAME);
  if WindowHandle <> 0 then
  begin
    if IsWindowEnabled(WindowHandle) then
      SetForegroundWindow(WindowHandle);

    FileName := GetCommandLineArgument(1);
    if FileName <> '' then
      FileName := MakeAbsoluteFileName(FileName);
    cds.dwData := TShellForm.COPY_DATA_ID_OPEN_FILE;
    cds.lpData := Pointer(FileName);
    cds.cbData := Length(FileName);
    {$HINTS OFF}
    SendMessage(WindowHandle, WM_COPYDATA, 0, LPARAM(@cds));
    {$HINTS ON}
  end;
end;

type
  TApplicationExceptionHandler = class
  private
    class procedure ApplicationException(Sender: TObject; E: Exception);
  end;

class procedure TApplicationExceptionHandler.ApplicationException(
  Sender: TObject; E: Exception);
begin
  if E is ECommandFailed then
    SysUtils.Beep
  else
    Application.MessageBox(PChar(E.Message), PChar(SIren), MB_OK or MB_ICONERROR);
end;

procedure Run;
var
  InstanceEvent: THandle;
  Form: TShellForm;
begin
  InstanceEvent := CreateEvent(nil, TRUE, FALSE, 'irenproject.ru-editorInstanceEvent');
  if InstanceEvent = 0 then
    raise Exception.Create('Can''t create InstanceEvent.');
  try
    if GetLastError = ERROR_ALREADY_EXISTS then
    begin
      if WaitForSingleObject(InstanceEvent, 5000) = WAIT_OBJECT_0 then
        ActivateExistingInstance;
    end
    else
    begin
      Application.Initialize;
      InitializeProgram;
      Application.OnException := TApplicationExceptionHandler.ApplicationException;

      Form := TShellForm.Open;

      if not SetProp(Form.Handle, MAIN_WINDOW_PROPERTY_NAME, THandle(-1)) then
        raise Exception.Create('SetProp failed.');
      try
        SetEvent(InstanceEvent);
        Application.Run;
      finally
        RemoveProp(Form.Handle, MAIN_WINDOW_PROPERTY_NAME);
      end;
    end;
  finally
    CloseHandle(InstanceEvent);
  end;
end;

begin
  try
    Run;
  except on E: Exception do
    MessageBox(0, PChar(E.Message), 'Initialization error', MB_ICONERROR);
  end;
end.
